package cn.lingyangwl.agile.pay.pay.listener;

import cn.lingyangwl.agile.pay.common.model.mq.RefundOrderMQ;
import cn.lingyangwl.agile.pay.common.service.RefundOrderService;
import cn.lingyangwl.framework.mq.base.manager.MqManager;
import cn.lingyangwl.agile.pay.model.entity.RefundOrder;
import cn.lingyangwl.agile.pay.pay.process.ChannelRefundOrderProcess;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 订单超时处理
 * 死信交换机
 * 定义死信队列
 *
 * @author shenguangyang
 */
@Component
@RabbitListener(queues = RefundOrderMQ.DELAY_QUEUE)
public class OrderRefundListener {
    private static final Logger log = LoggerFactory.getLogger(OrderRefundListener.class);

    @Resource
    private MqManager mqManager;
    @Resource
    private ChannelRefundOrderProcess channelRefundOrderProcess;
    @Resource
    private RefundOrderService refundOrderService;

    @RabbitHandler
    public void onMessage(String msg, Channel channel, Message message) {
        try {
            log.info("开始执行退款业务, msg: {}", msg);
            RefundOrderMQ.MsgPayload msgPayload = RefundOrderMQ.parse(msg, RefundOrderMQ.MsgPayload.class);
            // 判断是否重复消费
            if (mqManager.isConsumed(msgPayload.getMsgId())) {
                log.warn("message {} are repeatedly consumed, do not perform business", msgPayload.getMsgId());
                return;
            }
            mqManager.markConsumed(msgPayload.getMsgId());

            RefundOrder refundOrder = refundOrderService.getById(msgPayload.getRefundOrderId());
            if (Objects.isNull(refundOrder)) {
                log.warn("退款订单 refundOrderId={} 不存在", msgPayload.getRefundOrderId());
                return;
            }
            channelRefundOrderProcess.processRefundOrder(refundOrder);
            log.info("{}", msgPayload);
        } catch (Exception e) {
            if (e instanceof NullPointerException) {
                e.printStackTrace();
            }
            log.error("exec fail: {}", e.getMessage());
            throw e;
        }
    }
}
